/*
 * L9Map.h
 *
 *  Created on: 2011-10-18
 *      Author: baixp
 */

#ifndef L9MAP_H_
#define L9MAP_H_
#include "L9Sprite.h"
#include "L9Animation.h"
#include "L9Rect.h"
namespace lib9bada {
class L9Map {
private:
	short _nMap_Modules;
	static const int K_Map_Module_Byte_Num = 10; //index,x,y,z,flag,pal,isP
	pByte _map_modules;
	short _nMap_Frames;
	static const int K_Map_Frame_Byte_Num = 7; //index,x,y,z
	pByte _map_frames;
	short _nMap_Animations;
	static const int K_Map_Animation_Byte_Num = 7; //index,x,y,z
	pByte _map_animations;

	short _nMap_Rects;
	static const int K_Map_Rect_Byte_Num = 8; //index,x,y
	vector<L9Rect> _map_rects; //left,top,right,bottom

	int nTiles_X; //地图上X方向Tile的个数
	int nTiles_Y; //地图上Y方向Tile的个数
	int Tile_X; //屏幕现在处于X方向的Tile
	int Tile_Y; //屏幕现在处于Y方向的Tile
	int nTiles_BufferX; //屏幕缓冲X方向Tile数
	int nTiles_BufferY; //屏幕缓冲Y方向Tile数
	bool bMoveEnd; //表示地图是否移动到末尾了
	vector<vector<short> > Map_Tile_Module_ID;
	vector<vector<byte> > Map_Tile_IsP;
	vector<vector<byte> > Map_Tile_Flag;
	vector<vector<byte> > Map_Tile_Pal;

	int _SCR_W;
	int _SCR_H;

	vector<int> mapModuleFilterIndex;
	vector<int> mapFrameFilterIndex;
	vector<int> mapAnimationFilterIndex;

	void PaintMapModule(Canvas* g,int map_module_index);
	void PaintMapFrame(Canvas* g, int map_frame_index);

	void UpdateMapAnimation(Canvas* g, int map_anim_index);
	/**
	 * 计算屏幕在地图上Tile
	 */
	void Calc_Tile_XY();

	int _Tmp_Map_Tile_X;
	int _Tmp_Map_Tile_Y;
	//减一的目的是为了边界问题
	void Calc_Tile_XY(int x, int y);
public:
//	L9Map();
	virtual ~L9Map();

	L9Sprite* pMapSprite;

	/**
	 * 移动地图的上下左右四个方向常量
	 */
	static const int K_Map_Direction_Up = 0;
	static const int K_Map_Direction_Down = 1;
	static const int K_Map_Direction_Left = 2;
	static const int K_Map_Direction_Right = 3;

	int Tile_W;
	int Tile_H;
	int screenOffsetX; //屏幕在地图上的坐标偏移X
	int screenOffsetY; //屏幕在地图上的坐标偏移Y

	vector<L9Animation> MapAnimations;
	/**
	 * 判断屏幕在地图上是否还处在滚动的状态中
	 * @return bool
	 */
	bool isInScrollingStatus();
	/**
	 * 构建地图,sprite提供地图数据,SCR_W和SCR_H表示手机的屏幕宽度和高度
	 * @param sprite
	 * @param SCR_W
	 * @param SCR_H
	 */
	L9Map(const char* file, int SCR_W, int SCR_H);

	/**
	 * 返回当前地图的地图Module数
	 * @return int
	 */
	int getMapModules();

	/**
	 * 返回当前地图的地图Frame数
	 * @return int
	 */
	int getMapFrames();

	/**
	 * 返回当前地图的地图Animation数
	 * @return int
	 */
	int getMapAnimations();

	/**
	 * 根据地图module的索引来获取ModuleID
	 * @param index int
	 * @return int
	 */
	int getModuleID(int index);

	/**
	 * 返回地图第index个Module的在地图上得X坐标
	 * @param index int
	 * @return int
	 */
	int getModuleX(int index);

	/**
	 * 返回地图第index个Module的在地图上得Y坐标
	 * @param index int
	 * @return int
	 */
	int getModuleY(int index);
	/**
	 * 返回地图Module的Z次序
	 * @param index int
	 * @return int
	 */
	int getModuleZ(int index);

	/**
	 * 返回地图Module的翻转标记
	 * @param index int
	 * @return int
	 */
	int getModuleFlag(int index);

	/**
	 * 返回地图Module的调色板
	 * @param index int
	 * @return int
	 */
	int getModulePal(int index);

	/**
	 * 返回地图module的属性,0表示可以通过,1表示不能通过
	 * @param index int
	 * @return int
	 */
	int getModuleProperty(int index);

	/**
	 * 根据索引返回地图FrameID
	 * @param index int
	 * @return int
	 */
	int getFrameID(int index);

	/**
	 * 返回地图Frame的X坐标
	 * @param index int
	 * @return int
	 */
	int getFrameX(int index);

	/**
	 * 返回地图Frame的Y坐标
	 * @param index int
	 * @return int
	 */
	int getFrameY(int index);
	/**
	 * 返回地图Frame的Z次序
	 * @param index int
	 * @return int
	 */
	int getFrameZ(int index);

	/**
	 * 根据索引返回地图AnimationID
	 * @param index int
	 * @return int
	 */
	int getAnimationID(int index);

	/**
	 * 返回地图Animation的X坐标
	 * @param index int
	 * @return int
	 */
	int getAnimationX(int index);

	/**
	 * 返回地图Animation的Y坐标
	 * @param index int
	 * @return int
	 */
	int getAnimationY(int index);

	/**
	 * 返回地图Animation的Z次序
	 * @param index int
	 * @return int
	 */
	int getAnimationZ(int index);

	/**
	 * 返回地图module在地图上的矩形
	 * @param index int
	 * @return L9Rect
	 */
	L9Rect getModuleRect(int index);
	/**
	 * 返回地图frame在地图上的矩形
	 * @param index int
	 * @return L9Rect
	 */
	L9Rect getFrameRect(int index);

	/**
	 * 返回地图Animation在地图上的矩形
	 * @param index int
	 * @return L9Rect
	 */
	L9Rect getAnimationRect(int index);

	/**
	 * 返回地图的宽
	 * @return int
	 */
	int getMapWidth();

	/**
	 * 返回地图的高
	 * @return int
	 */
	int getMapHeight();

	static const int K_Map_Obejct_Type_Module = 0;
	static const int K_Map_Obejct_Type_Frame = 1;
	static const int K_Map_Obejct_Type_Animation = 2;

	/**
	 * 判断module,frame,animation对象是否在屏幕内
	 * @param type int
	 * @param index int
	 * @return bool
	 */
	bool isInScreen(int spriteType, int index);
	/**
	 * 返回地图中物品对象的最大层次数，为了效果的逼真，地图上往往会放置好几层物品
	 * @return int
	 */
	int getMaxZ();

	/**
	 * 在绘制地图的时候，有时希望有些对象不显示，这个函数的作用就是过滤掉哪些不显示的module对象
	 * 注意参数filterIndex是对象在地图中的索引，不是对象本身的id
	 * @param filterIndex int[]
	 */
	void setMapModuleFilter(vector<int> filterIndex);

	/**
	 * 返回地图上被过滤(也就是不会显示)的module对象在地图上的索引数组
	 * @return int[]
	 */
	vector<int> getMapModuleFilter();

	/**
	 * 在绘制地图的时候，有时希望有些对象不显示，这个函数的作用就是过滤掉哪些不显示的frame对象
	 * 注意参数filterIndex是对象在地图中的索引，不是对象本身的id
	 * @param filterIndex int[]
	 */
	void setMapFrameFilter(vector<int> filterIndex);
	/**
	 * 返回地图上被过滤(也就是不会显示)的frame对象在地图上的索引数组
	 * @return int[]
	 */
	vector<int> getMapFrameFilter();

	/**
	 * 在绘制地图的时候，有时希望有些对象不显示，这个函数的作用就是过滤掉哪些不显示的animation对象
	 * 注意参数filterIndex是对象在地图中的索引，不是对象本身的id
	 * @param filterIndex int[]
	 */
	void setMapAnimationFilter(vector<int> filterIndex);
	/**
	 * 返回地图上被过滤(也就是不会显示)的animation对象在地图上的索引数组
	 * @return int[]
	 */
	vector<int> getMapAnimationFilter();
	/**
	 * 绘制地图上的对象，当且仅当对象在屏幕内才且索引没有被过滤才绘制，绘制的时候是根据对象的Z顺序来进行绘制，Z越大越在上面绘制
	 * @param g
	 * @param p
	 */
	void updateMapObjects(Canvas* g);

	/**
	 * 返回地图上module的宽
	 * @param index int
	 * @return int
	 */
	int getModuleWidth(int index);

	/**
	 * 返回地图上module的高
	 * @param index int
	 * @return int
	 */
	int getModuleHeight(int index);
	/**
	 * 返回地图上module的Alpha
	 * @param index int
	 * @return bool
	 */
	bool getModuleAlpha(int index);
	/**
	 * 返回地图上frame的宽
	 * @param index int
	 * @return int
	 */
	int getFrameWidth(int index);
	/**
	 * 返回地图上frame的高
	 * @param frame int
	 * @return int
	 */
	int getFrameHeight(int index);
	/**
	 * 返回地图上animation的宽，动画的宽为动画所有帧的宽的并集
	 * @param index int
	 * @return int
	 */
	int getAnimationWidth(int index);

	/**
	 * 获取地图上动画的高
	 * @param anim int
	 * @return int
	 */
	int getAnimationHeight(int index);

	/**
	 * 返回地图上某个动画的fps
	 * @param anim int
	 * @return int
	 */
	int getAnimationFPS(int index);

	/**
	 * 缓存地图背景，在游戏中地图一般由tile构成，为了提供速度地图常常要求缓存
	 */
	void cacheMapBg();

	/**
	 * 判断该地图坐标x,y(x,y为地图上的任意一个点)所对应的tile是否为物理层,如果为物理层主角一般设置为不能通过
	 * @param x int
	 * @param y int
	 * @return bool
	 */
	bool isMapTilePhysical(int x, int y);
	/**
	 * 参数为手机屏幕的高和宽，手机屏幕外的物品和地图则不用绘制
	 * @param scrW int
	 * @param scrH int
	 */
	void initMap();
	/**
	 * 允许在整个地图范围内移动，如果要限制在地图的一部分范围内移动则使用MoveLimitMap函数
	 * @param Direction int
	 * @param Step int
	 */
	void moveMap(int Direction, int Step);

	/**
	 * 移动地图，根据游戏需要可以限制在地图的一部分范围内移动，方向为上下左右4个方向(对应常量K_Map_Direction_Up=0,K_Map_Direction_Down=1,K_Map_Direction_Left=2,K_Map_Direction_Right=3)
	 * @param Direction int
	 * @param Step int
	 * @param map_W int
	 * @param map_H int
	 */
	void moveLimitMap(int Direction, int Step, int map_W, int map_H);

	/**
	 * 更新绘制地图,只绘制在屏幕内的地图
	 * @param g
	 * @param p
	 */
	void updateMap(Canvas* g);
};
};

#endif /* L9MAP_H_ */
